package com.threeonemeeting.task;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;

import com.snda.lib.http.HttpUtil;
import com.snda.lib.http.ICallBack;
import com.snda.lib.http.IDownloadCallBack;
import com.snda.lib.task.DownloadFileNotifiedTask;
import com.snda.lib.util.IntentHelper;
import com.snda.lib.util.MiscHelper;
import com.threeonemeeting.Const;
import com.threeonemeeting.DataCenter;
import com.threeonemeeting.R;
import com.threeonemeeting.activity.DownloadActivity;
import com.threeonemeeting.model.DownloadInfo;
import com.threeonemeeting.model.DownloadInfoList;
import com.threeonemeeting.model.MeetingDataDocInfo;
import com.threeonemeeting.util.AppSettings;

public class DownloadDocumentFileTask extends DownloadFileNotifiedTask {

	public static final String APK_DOWNLOAD_KEY_APPKEY = "appkey";
	public static final String APK_DOWNLOAD_KEY_TITLE = "title";
	public static final String APK_DOWNLOAD_KEY_BITMAP = "bitmap";

	protected Activity activity;
	protected String strAppKey = "";
	protected String strFileTitle = "";
	protected String strFileName = "";

	protected long nCurrentFinishedSize = 0;
	protected int nCurrentNotifyProcessPercent = 0;

	private AtomicInteger ratio = new AtomicInteger(0);
	private UpdateThread mUpdateThread;
	private boolean bExistNotifyThread = false;

	public DownloadDocumentFileTask(Context context, ICallBack callback) {
		super(context, callback);

		this.nTaskType = HttpConst.TASKTYPE_DOWNLOADAPKFILE;
	}

	public void setAppKey(String strAppKey) {
		this.strAppKey = strAppKey;
	}

	public void setFileTitle(String strFileTitle) {
		this.strFileTitle = strFileTitle;
	}

	public void setFileName(String strFileName) {
		this.strFileName = strFileName;
	}

	public void setDocInfo(MeetingDataDocInfo docInfo) {
		if (docInfo == null)
			return;

		this.strAppKey = String.valueOf(docInfo.nDocId);
		this.strFileTitle = docInfo.strFileTitle;
		this.strFileName = docInfo.strFileName;

		setUrl(Const.URL.BASE_SERVER_URL + docInfo.strFileUrl);
		setSavePath(AppSettings.getFilePath(context.getApplicationContext()));
		setContinue(true);
	}

	private String getShowText() {
		if (MiscHelper.isEmpty(strFileTitle) != true)
			return strFileTitle;

		if (strFileName.length() > 8)
			strFileName = strFileName.substring(0, 8) + "...";

		return strFileName;
	}

	@Override
	public void cancelTask() {
		super.cancelTask();
		bExistNotifyThread = true;
	}

	@Override
	public boolean OnStartTask(String strUrl, String strSavePath) {
		return true;
	}

	/*
	 * 通知下载任务开始
	 */
	@Override
	public void OnBeginTask(String strUrl, long nFinishedSize,
			String strSavePath) {
		Log.d(Const.Tag, "begin to download :" + strUrl);

		// 取消上次的通知
		updateNotificationManager.cancel(nCookie);

		// 设置通知栏显示内容
		updateNotification.icon = android.R.drawable.stat_sys_download;
		updateNotification.flags = Notification.FLAG_AUTO_CANCEL;
		updateNotification.tickerText = "正在下载" + getShowText();

		RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
				R.layout.ac_notification);
		updateNotification.contentView = mRemoteViews;

		int nPercent = (int) (nFinishedSize * 100 / nTotalSize);
		updateNotification.contentView.setTextViewText(R.id.rc_title,
				getShowText());
		updateNotification.contentView.setProgressBar(R.id.rc_progress_bar,
				100, nPercent, false);
		updateNotification.contentView.setTextViewText(R.id.rc_progress_text,
				nPercent + "%");

		Intent intent = new Intent(context, DownloadActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_NEW_TASK);

		PendingIntent contentIntent = PendingIntent.getActivity(context,
				nCookie, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		updateNotification.contentIntent = contentIntent;
		updateNotificationManager.notify(nCookie, updateNotification);

		mUpdateThread = new UpdateThread();
		mUpdateThread.start();

		DownloadInfoList downloadList = DataCenter.getInstance().listDownload;
		DownloadInfo dInfo = null;
		if (downloadList != null) {

			dInfo = downloadList.getDownloadInfoByUrl(strUrl);
			if (dInfo != null) {
				dInfo.nStatus = DownloadInfo.DOWNLOAD_STATUS_RUNNING;
				return;
			}
		}

		// 启动下载，增加一个DownloadInfo结构
		DownloadInfo downloadData = new DownloadInfo();
		downloadData.nCookie = nCookie;
		downloadData.strAppKey = strAppKey;
		downloadData.nStatus = DownloadInfo.DOWNLOAD_STATUS_RUNNING;
		downloadData.strFileName = strDownloadFileName;
		downloadData.nFileSize = nTotalSize;
		downloadData.nFileDownloadedSize = nFinishedSize;
		downloadData.nDownloadTime = System.currentTimeMillis();
		downloadData.strFileUrl = strUrl;

		if (strSavePath == null) {
			downloadData.strLocalPath = "";
		} else {
			downloadData.strLocalPath = strSavePath;
		}

		downloadData.strFileTitle = getShowText();

		DataCenter.getInstance().listDownload.addDownloadInfo(downloadData);
	}

	/*
	 * 通知当前的下载进度
	 * 
	 * @param nFinishedSize 已经下载的总长度
	 */
	@Override
	public void OnNotifyProcess(long nFinishedSize) {
		// 通知进度
		int nPercent = (int) (nFinishedSize * 100 / nTotalSize);
		ratio.set(nPercent);

		if (nCurrentPercent != nPercent) {
			DownloadInfo data = DataCenter.getInstance().listDownload
					.getDownloadInfo(strAppKey);
			if (data != null) {
				data.nFileDownloadedSize = nFinishedSize;
			}

			nCurrentPercent = nPercent;
		}

		// 保存进度
		if (nFinishedSize - nCurrentFinishedSize > 1024 * 100) {
			DataCenter.getInstance().getDB()
					.updateDownloadInfo(strAppKey, nFinishedSize);
			nCurrentFinishedSize = nFinishedSize;
		}

	}

	/*
	 * 通知当前的任务已经下载完毕
	 */
	@Override
	public void OnFinishedTask(String strDownloadPath) {
		super.OnFinishedTask(strDownloadPath);

		bExistNotifyThread = true;

		Intent installIntent = IntentHelper.getOpenFileIntent(strDownloadPath);
		PendingIntent updatePendingIntent = PendingIntent.getActivity(context,
				0, installIntent, 0);

		if (MiscHelper.isEmpty(strFileTitle) != true) {
			updateNotification.setLatestEventInfo(context, strFileTitle,
					"下载完成，点击打开", updatePendingIntent);

		} else if (MiscHelper.isEmpty(strDownloadFileName) != true) {
			updateNotification.setLatestEventInfo(context, strDownloadFileName,
					"下载完成，点击打开", updatePendingIntent);
		}

		updateNotificationManager.notify(nCookie, updateNotification);

		// 下载完毕，此时添加到DownloadInfo中去
		DownloadInfo data = DataCenter.getInstance().listDownload
				.getDownloadInfo(strAppKey);
		if (data != null) {
			data.nStatus = DownloadInfo.DOWNLOAD_STATUS_FINISHED;
			data.strLocalPath = strDownloadPath;

			DataCenter.getInstance().getDB().addDownloadInfo(data);
		}
	}

	/**
	 * 通知已经全部下载完毕，不需要进行任何下载
	 * 
	 * @param strDownloadPath
	 *            已经下载的文件的路径
	 */
	public void OnAlreadyDownload(long nTotalSize, String strDownloadPath) {
		super.OnAlreadyDownload(nTotalSize, strDownloadPath);

		if (objCallBack != null && objCallBack.get() != null) {
			IDownloadCallBack dCallBack = (IDownloadCallBack) objCallBack.get();
			if (dCallBack != null) {
				dCallBack.onAlreadyDownloaded(strDownloadPath);
			}
		}
	}

	/**
	 * @desc 通知当前的任务下载发生失败
	 * @param nErrorCode
	 *            失败的错误码
	 */
	@Override
	public void OnFailed(int nErrorCode) {
		super.OnFailed(nErrorCode);

		bExistNotifyThread = true;

		// 下载完毕，此时添加到DownloadInfo中去
		DownloadInfo data = DataCenter.getInstance().listDownload
				.getDownloadInfo(strAppKey);
		if (data != null) {
			data.nStatus = DownloadInfo.DOWNLOAD_STATUS_FAILED;
		}
	}

	@Override
	protected Map<String, Object> process(Map<String, Object> map) {

		Map<String, Object> mapData = new HashMap<String, Object>();
		mapData.put(HttpUtil.KEY_TASK_TYPE, nTaskType);
		mapData.put(APK_DOWNLOAD_KEY_APPKEY, strAppKey);

		Integer nError = (Integer) map.get(HttpUtil.KEY_ERROR_CODE);
		if (nError == null) {
			setErr(HttpUtil.ERROR_UNKNOWN, mapData);
			return mapData;
		}

		if (nError != HttpUtil.ERROR_SUCCESS
				&& nError != HttpUtil.ERROR_ALREADY_EXIST) {
			setErr(nError, mapData);
			return mapData;
		}

		String strSavePath = (String) map.get(HttpUtil.KEY_PATH);
		if (strSavePath == null) {
			setErr(HttpUtil.ERROR_INVALID_SAVE_PATH, mapData);
			return mapData;
		}

		setErr(nError, mapData);
		mapData.put(HttpUtil.KEY_PATH, strSavePath);
		return mapData;
	}

	final class UpdateThread extends Thread {

		@Override
		public void run() {

			int nPercent = ratio.get();
			while (nPercent <= 100) {

				if (bExistNotifyThread == true)
					return;

				String strShowText = getShowText();

				// 通知进度条，因为进度条多的时候会导致卡，所以控制进度条的通知频率
				updateNotification.contentView.setTextViewText(R.id.rc_title,
						strShowText);
				updateNotification.contentView.setTextViewText(
						R.id.rc_progress_text, nPercent + "%");
				updateNotification.contentView.setProgressBar(
						R.id.rc_progress_bar, 100, nPercent, false);

				updateNotificationManager.notify(nCookie, updateNotification);

				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					break;
				}

				nPercent = ratio.get();
			}
		}

	}
}